#include <string>
#include <vector>
#include <list>
#include <map>

#include "XMLUtil.h"


using namespace std;

namespace helix
{

	XMLNode::XMLNode()
	{
		tagName="";
		value="";
		children=new XMLElementChildrenList();
		attributes=new XMLElementAttributes();
	}

	XMLNode::~XMLNode()
	{
		if(children)
		{
			delete children;
		}	
		if(attributes)
		{
			delete attributes;
		}
	}

	void XMLNode::setTagName(string tagName)
	{
		this->tagName=tagName;
	}

	string XMLNode::getTagName()
	{
		return tagName;
	}

	void XMLNode::setValue(string value)
	{
		this->value=value;
	}

	string XMLNode::getValue()
	{
		return value;
	}

	int XMLNode::numChildren()
	{
		return children->size();
	}

	int XMLNode::numAttributes()
	{
		return attributes->size();
	}

	void XMLNode::addChild(XMLNode *node)
	{
		children->addChild(node);
	}

	void XMLNode::addAttribute(string attribute,string value)
	{
		attributes->addAttribute(attribute,value);
	}

	string XMLNode::getAttribute(string attribute)
	{
		return attributes->getAttribute(attribute);
	}

	string XMLNode::getAttribute(int index)
	{
		return attributes->getAttribute(index);
	}

	XMLNode *XMLNode::getChild(int index)
	{
		return children->getChild(index);
	}

	/********************************************************************
	***            Start XMLElementChildrenList class                  **
	********************************************************************/

	XMLElementChildrenList::XMLElementChildrenList()
	{
		children=new vector<XMLNode*>();
	}

	XMLElementChildrenList::~XMLElementChildrenList()
	{
		vector<XMLNode*>::iterator itr;
		itr = children->begin();
		while( itr != children->end() )
		{
			//Delete every XMLNode on the children list
			XMLNode* node= *itr;
			delete node;
			itr++;
		}
		//Finally, delete the children list
		delete children;
	}

	void XMLElementChildrenList::addChild(XMLNode *node)
	{
		children->push_back(node);
	}

	XMLNode *XMLElementChildrenList::getChild(int index)
	{
		if(index<0 || index>=(int)children->size())
			return NULL;
		
		return children->at(index);
	}

	int XMLElementChildrenList::size()
	{
		return (int)children->size();
	}


	/********************************************************************
	***            Start XMLElementAttributes class                  **
	********************************************************************/
	XMLElementAttributes::XMLElementAttributes()
	{
		attributes=new map<string,string>();
	}

	XMLElementAttributes::~XMLElementAttributes()
	{
		delete attributes;
	}

	void XMLElementAttributes::addAttribute(string attrib,string value)
	{
		attributes->insert(make_pair(attrib,value));
	}

	string XMLElementAttributes::getAttribute(string attrib)
	{
		map<string,string>::iterator itr=attributes->find(attrib);
		if(itr==attributes->end())
			return "";

		return itr->second;
	}

	string XMLElementAttributes::getAttribute(int index)
	{
		map<string,string>::iterator itr=attributes->begin();
		if (index<0||index>=size())
			return "";
		for(int i=0;i<index;i++)
			itr++;

		return itr->second;
	}

	int XMLElementAttributes::size()
	{
		return (int)attributes->size();
	}

}
